﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Graphics;

namespace GameBase
{
    public class VisibleGameEntity<T> : GameEntity<T>,ICloneable
    {

        private bool _listenEvent = false;
 
        public virtual bool ListenEvent
        {
            get { return _listenEvent; }
            set { _listenEvent = value; }
        }

        protected int _index;

        public virtual int Index
        {
            get { return _index; }
            protected set { _index = value; }
        }
        protected enum VisibleGameState
        {
            MouseHover, Click, MouseEnter, Idle
        }

        private Boolean _visible = true;
        private VisibleGameState _state = VisibleGameState.Idle;
        private Boolean _focus = false;

        public Boolean Focus
        {
            get { return _focus; }
            set { _focus = value; }
        }
        public virtual Boolean Visible
        {
            get { return _visible; }
            set { _visible = value; }
        }
        protected VisibleGameState State
        {
            get { return _state; }
            set { _state = value; }
        }

        public event EventHandler MouseClick;
        public event EventHandler MouseHover;
        public event EventHandler MouseEnter;
        public event EventHandler MouseLeave;

        public void Draw(GameTime gameTime,SpriteBatch spriteBatch,  Object extraData)
        {
            if (Visible)
                Paint(gameTime,spriteBatch ,extraData);
        }

        protected virtual void Paint(GameTime gameTime, SpriteBatch spriteBatch, Object extraData)
        {

        }
        protected override void UpdateEntitys(GameTime gameTime, object extraData)
        {
            if (!ListenEvent)
                return;
            MouseState mouseState = Mouse.GetState();

            if (Contains(mouseState.X, mouseState.Y))
            {
                if (State == VisibleGameState.Idle)
                {
                    State = VisibleGameState.MouseEnter;
                    this.Focus = true;
                    OnMouveEnter(mouseState);
                    if (MouseEnter != null)
                    {
                        MouseEnter(this, EventArgs.Empty);
                    }
                }
                else if (State != VisibleGameState.MouseHover)
                {
                    State = VisibleGameState.MouseHover;
                    OnHover(mouseState);
                    if (MouseHover != null)
                    {
                        MouseHover(this, EventArgs.Empty);
                    }
                }
            }
            else if (State != VisibleGameState.Idle)
            {
                State = VisibleGameState.Idle;
                this.Focus = false;
                OnMouveLeave(mouseState);
                if (MouseLeave != null)
                {
                    MouseLeave(this, EventArgs.Empty);
                }
            }
            if (IsClick(mouseState))
            {
                State = VisibleGameState.Click;
                OnClick(mouseState);
                if (MouseClick != null)
                {
                    MouseClick(this, EventArgs.Empty);
                }
            }
        }

        public bool IsClick(MouseState mouseState)
        {
            if (mouseState.LeftButton == ButtonState.Pressed
                || mouseState.RightButton == ButtonState.Pressed
                || mouseState.MiddleButton == ButtonState.Pressed)
            {
                return Contains(mouseState.X, mouseState.Y);
            }
            return false;
        }
        public bool Contains(Vector2 point)
        {
            return Contains(point.X, point.Y);
        }
        public virtual bool Contains(float x, float y)
        {
            if (x >= Position.X && x <= Position.X + Size.X
                && y >= Position.Y && y <= Position.Y + Size.Y
                )
            {
                return true;
            }
            return false;
        }

        protected virtual void OnClick(MouseState mouse)
        {
        }
        protected virtual void OnHover(MouseState mouseState)
        {
        }
        protected virtual void OnMouveLeave(MouseState mouseState)
        {
        }
        protected virtual void OnMouveEnter(MouseState mouseState)
        {
        }

        public virtual object Clone()
        {
            throw new NotImplementedException();
        }

        public virtual int GetDepth() 
        {
            return 0;
        }
    }
}